package com.yuda.campsite.controller;

import cn.hutool.core.lang.Tuple;
import com.yuda.campsite.domain.CampsiteConf;
import com.yuda.campsite.dto.*;
import com.yuda.campsite.service.ICampsiteConfService;
import com.yuda.campsite.service.IInvitationCodeService;
import com.yuda.campsite.util.GeneratorInvitationCode;
import com.yuda.common.core.utils.poi.ExcelUtil;
import com.yuda.common.core.web.controller.BaseController;
import com.yuda.common.core.web.domain.AjaxResult;
import com.yuda.common.core.web.page.TableDataInfo;
import com.yuda.common.log.annotation.Log;
import com.yuda.common.log.enums.BusinessType;
import com.yuda.common.security.annotation.PreAuthorize;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import reactor.util.function.Tuple6;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 邀请码Controller
 *
 * @author wyn
 * @date 2021-09-29
 */
@RestController
@RequestMapping("/code")
public class InvitationCodeController extends BaseController {

    @Autowired
    private IInvitationCodeService invitationCodeService;

    @Autowired
    private GeneratorInvitationCode generatorInvitationCode;

    @Autowired
    private ICampsiteConfService campsiteConfService;


    /**
     * 邀请码统计 一级菜单
     *
     * @param campsiteId 营地id
     */
    @ApiOperation("邀请码统计一级菜单")
    @GetMapping("/categoryList")
    public TableDataInfo categoryList(@RequestParam Integer campsiteId) {
        startPage();
        List<InvitationCategory> list = invitationCodeService.categoryList(campsiteId);
        return getDataTable(list);
    }


    /**
     * 邀请码统计 二级菜单
     *
     * @param campsiteId 营地id
     * @param reduction  减免金额
     */
    @ApiOperation("邀请码统计二级菜单")
    @GetMapping("/categoryDetailList")
    public TableDataInfo categoryDetailList(@RequestParam Integer campsiteId, @RequestParam String reduction) {
        startPage();
        List<InvitationCategoryDetail> list = invitationCodeService.categoryDetailList(campsiteId, reduction);
        return getDataTable(list);
    }


    /**
     * 邀请码统计 导表
     *
     * @param campsiteId 营地id
     * @param reduction  减免金额
     * @param name       邀请码名称
     */
    @ApiOperation("邀请码统计导表")
    @PostMapping("/exportCategoryDetailList")
    public void exportCategoryDetailList(HttpServletResponse response,
                                         @RequestParam Integer campsiteId,
                                         @RequestParam String reduction,
                                         @RequestParam String name) throws IOException {

        List<InvCodeWithStuInfo> list = invitationCodeService.getInvCodeWithStuInfo(campsiteId, reduction, name);

        //数据统计
        //1.已使用邀请码
        //2.已提交未审核
        long pass = list.stream().filter(x -> x.getExamineStatus() != null && x.getExamineStatus().equals("通过") && x.getTempOrderStatus() != null && x.getTempOrderStatus() >= 3 && x.getTempOrderStatus() <= 6).count();
        long bmOver = list.stream().filter(x -> x.getOrderStatus() != null && x.getOrderStatus().equals("报名完成")).count();
        Tuple objects = new Tuple(
                list.stream().filter(x -> x.getInvStatus().equals("已使用")).count(),
                list.stream().filter(x -> x.getExamineStatus() != null && x.getExamineStatus().equals("未审核") && x.getTempOrderStatus() != null && x.getTempOrderStatus() >= 3 && x.getTempOrderStatus() <= 6).count(),
                list.stream().filter(x -> x.getExamineStatus() != null && x.getExamineStatus().equals("未通过") && x.getTempOrderStatus() != null && x.getTempOrderStatus() >= 3 && x.getTempOrderStatus() <= 6).count(),
                pass - bmOver,
                list.stream().filter(x -> x.getOrderStatus() != null && x.getOrderStatus().equals("待支付")).count(),
                bmOver);

        //暂时写死，有更好的方法解决
        Tuple objectsZh = new Tuple("已使用邀请码", "已提交审核资料（未审核）", "已提交审核资料（审核未通过）", "已提交审核资料（审核通过）", "待支付", "报名完成");
        //list中添加几个空数据 占位
        for (int i = 0; i < 5; i++) {
            list.add(new InvCodeWithStuInfo());
        }
        InvCodeWithStuInfo invCodeWithStuInfo = new InvCodeWithStuInfo();
        invCodeWithStuInfo.setName("合计");
        invCodeWithStuInfo.setIdCard("");
        invCodeWithStuInfo.setPhone("状态");
        invCodeWithStuInfo.setCode("人数");
        list.add(invCodeWithStuInfo);

        int index = 0;
        for (Object o : objectsZh) {
            InvCodeWithStuInfo invCodeWithStuInfo2 = new InvCodeWithStuInfo();
            invCodeWithStuInfo2.setPhone((String) o);
            invCodeWithStuInfo2.setCode(objects.get(index++) + "");
            list.add(invCodeWithStuInfo2);
        }
        ExcelUtil<InvCodeWithStuInfo> invitationWithStuInfoExcelUtil = new ExcelUtil<>(InvCodeWithStuInfo.class);
        invitationWithStuInfoExcelUtil.exportExcel(response, list, "code");
    }


    /**
     * 查询邀请码列表
     */
//    @PreAuthorize(hasPermi = "yingdi:code:list")
    @GetMapping("/list")
    public TableDataInfo list(InvitationWithStuInfo invitationWithStuInfo) {
        startPage();

        List<InvitationWithStuInfo> list = invitationCodeService.selectInvitationCodeList(invitationWithStuInfo);
        for (InvitationWithStuInfo withStuInfo : list) {
            if (withStuInfo.getStatus() != null && withStuInfo.getStatus().equals("0")) {
                withStuInfo.setStatus("进入报名流程");
            }
            if (withStuInfo.getStatus() != null && withStuInfo.getStatus().equals("1")) {
                withStuInfo.setStatus("已阅读报名须知");
            }
            if (withStuInfo.getStatus() != null && withStuInfo.getStatus().equals("2") && withStuInfo.getInvCode() == null) {
                withStuInfo.setStatus("未使用邀请码");
            }
            if (withStuInfo.getStatus() != null && withStuInfo.getStatus().equals("2") && withStuInfo.getInvCode() != null) {
                withStuInfo.setStatus("已使用邀请码");
            }
            if (withStuInfo.getStatus() != null && withStuInfo.getStatus().equals("3")) {
                withStuInfo.setStatus("已填写报名资料");
            }
            if (withStuInfo.getStatus() != null && withStuInfo.getStatus().equals("4") && withStuInfo.getExamineStatus() != null && withStuInfo.getExamineStatus().equals("0")) {
                withStuInfo.setStatus("已提交审核资料(未审核)");
            }
            if (withStuInfo.getStatus() != null && withStuInfo.getStatus().equals("4") && withStuInfo.getExamineStatus() != null && withStuInfo.getExamineStatus().equals("1")) {
                withStuInfo.setStatus("已提交审核资料(审核通过)");
            }
            if (withStuInfo.getStatus() != null && withStuInfo.getStatus().equals("4") && withStuInfo.getExamineStatus() != null && withStuInfo.getExamineStatus().equals("2")) {
                withStuInfo.setStatus("已提交审核资料(审核未通过)");
            }
            if (withStuInfo.getStatus() != null && withStuInfo.getStatus().equals("5")) {
                withStuInfo.setStatus("待支付");
            }
            if (withStuInfo.getStatus() != null && withStuInfo.getStatus().equals("6")) {
                withStuInfo.setStatus("报名完成");
            }
        }
        return getDataTable(list);
    }

    /**
     * 导出邀请码列表
     */
    @PreAuthorize(hasPermi = "campSystem:campManager:invite:export")
    @Log(title = "邀请码", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, InvitationWithStuInfo invitationWithStuInfo) throws IOException {
        List<InvitationWithStuInfo> list = invitationCodeService.selectInvitationCodeList(invitationWithStuInfo);
        for (InvitationWithStuInfo withStuInfo : list) {
            if (withStuInfo.getInvCode() != null) {
                withStuInfo.setInvUsed(withStuInfo.getInvUsed().equals("2") ? "已使用" : "未使用");
            }
            if (withStuInfo.getStatus() != null) {
                withStuInfo.setStatus(withStuInfo.getStatus().equals("6") ? "支付成功" : "还未支付");
            }
        }
        ExcelUtil<InvitationWithStuInfo> invitationWithStuInfoExcelUtil = new ExcelUtil<>(InvitationWithStuInfo.class);
        invitationWithStuInfoExcelUtil.exportExcel(response, list, "code");
    }

    /**
     * 新增邀请码
     * <p>
     * 此方法 需要处理 1.邀请码类型的添加  2. 邀请码的生成/获取 3.邀请码的类型类型表和邀请码表数据一致性
     */
    @PreAuthorize(hasPermi = "campSystem:campManager:invite:add")
    @Log(title = "邀请码", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody @Valid SimpleInvCodeForGen simpleInvCodeForGen) {
        BigDecimal reduction = simpleInvCodeForGen.getReduction();
        //减免金额不能超过总金额
        CampsiteConf campsiteConf = campsiteConfService.selectCampsiteConfById(simpleInvCodeForGen.getCampsiteId().longValue());
        String registrationFee = campsiteConf.getRegistrationFee();
        if (reduction.intValue() > Integer.parseInt(registrationFee)) {
            return AjaxResult.error("减免金额不可以大于总金额");
        }

        //查询邀请码名称是否已经使用过
        int isUsed = invitationCodeService.invCodeNameisUsed(simpleInvCodeForGen);
        if (isUsed > 0) {
            return AjaxResult.error("该营地邀请码名称已经被使用过");
        }

        return toAjax(invitationCodeService.insertInvitationCode(simpleInvCodeForGen));

    }

    /**
     * 追加邀请码
     */
    @PreAuthorize(hasPermi = "campSystem:campManager:invite:add")
    @Log(title = "邀请码", businessType = BusinessType.INSERT)
    @PostMapping("/append")
    public AjaxResult append(@RequestBody @Valid SimpleInvCodeForGen simpleInvCodeForGen) {
        //根据邀请码名称查询邀请码减免金额
        String name = simpleInvCodeForGen.getName();
        String f = campsiteConfService.getRegistrationFee(name, simpleInvCodeForGen.getCampsiteId());
        simpleInvCodeForGen.setReduction(new BigDecimal(f));
        return toAjax(invitationCodeService.appendInvitationCode(simpleInvCodeForGen));
    }


    /**
     * 管理员才可以执行，手动
     *
     * @return
     */
    @Log(title = "调用邀请码生成", businessType = BusinessType.OTHER)
    @PostMapping("/invokeGenInvCode")
//    @PreAuthorize(hasAnyRoles = "admin")
    public AjaxResult invokeGenInvCode() {
        try {
            generatorInvitationCode.generatorInvitationCode();
        } catch (Exception e) {
            return AjaxResult.success("调用失败");
        }
        return AjaxResult.success("调用完毕");
    }

    @GetMapping("/names")
    public AjaxResult names(Integer campsiteId) {
        List<String> names = invitationCodeService.name(campsiteId);
        return AjaxResult.success(names);
    }

}
